home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir30
/
alsps.zip
/
ALSP8.DOC
< prev
next >
Wrap
Lisp/Scheme
|
1993-11-04
|
7KB
|
220 lines
This is Lesson 8 of a series of AutoLISP training exercises given
on the CompuServe ADESK Forum by the Autodesk, Inc. Training
Department.
PREDICATES, LOGICAL OPERATORS, AND CONDITIONAL EXPRESSIONS, PART
ONE
BRANCHING
The ability to examine the state of one or more settings (or
variables) and make a decision based on the state(s) whether or
not to execute a program expression is a fundamental and
powerful facility in AutoLISP. This form of decision-making may
be referred to as a conditional branch, that is, a branch in the
program logic to execute or not execute a particular program
expression, or to execute one program expression rather than
another, based on some condition that exists.
You and I make these kinds of decisions all the time. If it is
sunny today, I will not take my umbrella with me to work. If the
gasoline costs less at a given service station, then I will
purchase gasoline there, rather than at another station.
In both of the previous examples, the word "if" is used as the
conditional expression, that is, the function that performs a
test to determine whether a particular state or condition exists.
The AutoLISP subr IF has virtually the same meaning as its use in
the previous, real-world examples.
THE IF STATEMENT
The subr IF is used to test the state of a single condition. If
the condition evaluates to a non-nil value, that is, anything BUT
nil, then the program expression immediately following the test
will be executed.
(if <test expression> <expression> [<expression>])
There must be one expression following the test expression.
Optionally, there may be a second expression that will be
evaluated if the test expression returns nil.
For example, this is the definition of a function to test whether
the value of variable X is greater than 0. If it is, then it
prints the statement "X greater than 0" on the display.
Edit a new file named GREATER.LSP and define this function.
(defun GREATER ()
(if
(> x 0)
(prompt "\nX is greater than 0.")
)
(prin1)
)
Command: (setq x 1)
1
Command: (load "greater")
GREATER
Command: (greater)
X is greater than 0.
Command: (setq x -1)
-1
Command: (greater)
There are a couple of things you can do to make the GREATER
function more versatile. First, make the value to be tested a
required argument to the function, so that GREATER doesn't depend
on the value of a particular global variable named X. Next, add
a second statement to the IF expression that prints a message if
the value of the required argument is LESS then or EQUAL TO zero.
Edit the file GREATER.LSP and make these two changes to the
GREATER function.
(defun GREATER (x)
(if
(> x 0)
(print "\nArgument is greater than 0.")
(print "\nArgument is less than or equal to 0.")
)
(prin1)
)
Command: (load "greater")
GREATER
Command: (greater 1)
Argument is greater than 0.
Command: (greater -1)
Argument is less than or equal to 0.
Command: (setq y 1)
1
Command: (greater y)
Argument is greater than 0.
A PRACTICAL USE FOR IF
One of the recent topics on the CompuServe ADESK Forum has been
the desire to change the END command so that it prompts the user
whether or not to really save the current state of the drawing
and exit the drawing editor, in the same manner that QUIT prompts
the user.
In the following example, you will write an AutoLISP function to
substitute for the native AutoCAD END command, and undefined the
native END command so that AutoCAD will use the AutoLISP function
in its place.
The new function will be defined so that it can be called
directly from the AutoCAD command prompt without first being
enclosed in parentheses, and will itself call the native END
command (regardless of whether END has been undefined) by
prefacing the command name with a period ".".
Edit a new file named END.LSP and add this function.
(defun C:END (/ usr)
; prompt the user and get a response
(setq usr (getstring "\nReally want to END the drawing? "))
; convert his response to upper case characters
(setq usr (strcase usr))
; test whether his response was "y" or "Y"
(if
(equal "Y" usr)
; if it was, then end the drawing, else print message
(command ".END")
(prompt "\nRemaining in drawing editor.")
)
; quiet exit if answer is anything but "y" or "Y"
(prin1)
)
UNDEFINE the native END command so that is may be replaced by the
AutoLISP-based C:END function (for more information about the
UNDEFINE command, please see your AutoCAD Reference Manual).
Command: UNDEFINE
Command name: END
Command: (load "end")
C:END
Command: END
Really want to END the drawing? n
Remaining in drawing editor.
Command: END
Really want to END the drawing? y
For the sake of efficiency and avoiding unnecessary variable
binding, which can be relatively expensive in terms of computer
time, the C:END function could also be written like this.
(defun C:END ()
(if
(eq "Y"
(strcase
(getstring "\nReally want to END the drawing? ")
)
)
(command ".END")
(prompt "\nRemaining in drawing editor.")
)
(prin1)
)
However, as you begin to learn AutoLISP, it's entirely
appropriate for you to use as many variable bindings as you like
if it helps you to keep things straight in your programs and your
own mind. There are all sorts of interesting things you can do
in AutoLISP to write efficient code, but until you have a firm
understanding of the basic mechanics, such an effort is likely to
be counter-productive. Who cares whether an additional 40
milliseconds of computer time was consumed by a variable binding
that strictly speaking didn't have to be there if it helps make
the program logic easier for you to understand?
Next week: Part Two
Exercise
1. Write a new function HIGHER. Here's what it should do.
a) Prompt the user to select two points.
b) Store the values of both points.
c) Test the Y values of both points.
d) If the Y value of the first point is greater, print a
message telling the user the first point is higher.
e) If the Y value of the second point is greater, print
a message telling the user the second point is higher.
Functions that you might want to use include GETPOINT, IF, DEFUN,
CAR, CDR, and >.
Note that you could include two separate IF statements, or
combine the two possible responses as the two expressions
following the text expression in a single IF statement. The
latter case is typically referred to as an IF-THEN-ELSE
statement.
(if
< this test expression is true >
< then do this expression>
< else do this expression, instead>
)